home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / CodeWarrior Lite / Metrowerks C⁄C++ Lite / Headers / ANSI Headers / bits < prev    next >
Encoding:
Text File  |  1995-04-25  |  5.2 KB  |  205 lines  |  [TEXT/MMCC]

  1. // bits standard header
  2. #ifndef _BITS_
  3. #define _BITS_
  4. #include <string>
  5.  
  6. #if __MWERKS__
  7. #pragma options align=mac68k
  8. #endif
  9.  
  10.         // template class bits
  11. string _Bitsxstr(istream&, size_t);
  12. template<size_t _N> class bits {
  13.     typedef unsigned long _T;
  14. public:
  15.     bits()
  16.         {_Tidy(); }
  17.     bits(unsigned long _X)
  18.         {_Tidy();
  19.         for (size_t _P = 0; _X != 0 && _P < _N; _X >>= 1, ++_P)
  20.             if (_X & 1)
  21.                 set(_P); }
  22.     bits(const string& _S, size_t _P = 0, size_t _L = NPOS)
  23.         {if (_S.length() < _P)
  24.             _Xran();
  25.         if (_S.length() - _P < _L)
  26.             _L = _S.length() - _P;
  27.         if (_N < _L)
  28.             _L = _N;
  29.         _Tidy(), _P += _L;
  30.         for (size_t _I = 0; _I < _L; ++_I)
  31.             if (_S[--_P] == '1')
  32.                 set(_I);
  33.             else if (_S[_P] != '0')
  34.                 _Xinv(); }
  35.     bits<_N>& operator&=(const bits<_N>& _R)
  36.         {for (int _I = _Nw; 0 <= _I; --_I)
  37.             _A[_I] &= _R._W(_I);
  38.         return (*this); }
  39.     bits<_N>& operator|=(const bits<_N>& _R)
  40.         {for (int _I = _Nw; 0 <= _I; --_I)
  41.             _A[_I] |= _R._W(_I);
  42.         return (*this); }
  43.     bits<_N>& operator^=(const bits<_N>& _R)
  44.         {for (int _I = _Nw; 0 <= _I; --_I)
  45.             _A[_I] ^= _R._W(_I);
  46.         return (*this); }
  47.     bits<_N>& operator<<=(size_t _P)
  48.         {if (_P < 0)
  49.             return (*this >>= -_P);
  50.         const int _D = _P / _Nb;
  51.         if (_D != 0)
  52.             for (int _I = _Nw; 0 <= _I; --_I)
  53.                 _A[_I] = _D <= _I ? _A[_I - _D] : 0;
  54.         if ((_P %= _Nb) != 0)
  55.             {for (int _I = _Nw; 0 < _I; --_I)
  56.                 _A[_I] = (_A[_I] << _P)
  57.                     | (_A[_I - 1] >> (_Nb - _P));
  58.             _A[0] <<= _P, _Trim(); }
  59.         return (*this); }
  60.     bits<_N>& operator>>=(size_t _P)
  61.         {if (_P < 0)
  62.             return (*this <<= -_P);
  63.         const int _D = _P / _Nb;
  64.         if (_D != 0)
  65.             for (int _I = 0; _I <= _Nw; ++_I)
  66.                 _A[_I] = _D <= _Nw - _I ? _A[_I + _D] : 0;
  67.         if ((_P %= _Nb) != 0)
  68.             {for (int _I = 0; _I < _Nw; ++_I)
  69.                 _A[_I] = (_A[_I] >> _P)
  70.                     | (_A[_I + 1] << (_Nb - _P));
  71.             _A[_Nw] >>= _P; }
  72.         return (*this); }
  73.     bits<_N>& set()
  74.         {_Tidy(~(_T)0);
  75.         return (*this); }
  76.     bits<_N>& set(size_t _P, _Bool _X = 1)
  77.         {if (_N <= _P)
  78.             _Xran();
  79.         if (_X)
  80.             _A[_P / _Nb] |= (_T)1 << _P % _Nb;
  81.         else
  82.             _A[_P / _Nb] &= ~((_T)1 << _P % _Nb);
  83.         return (*this); }
  84.     bits<_N>& reset()
  85.         {_Tidy();
  86.         return (*this); }
  87.     bits<_N>& reset(size_t _P)
  88.         {return (set(_P, 0)); }
  89.     bits<_N> operator~() const
  90.         {return (bits<_N>(*this).toggle()); }
  91.     bits<_N>& toggle()
  92.         {for (int _I = _Nw; 0 <= _I; --_I)
  93.             _A[_I] = ~_A[_I];
  94.         _Trim();
  95.         return (*this); }
  96.     bits<_N>& toggle(size_t _P)
  97.         {if (_N <= _P)
  98.             _Xran();
  99.         _A[_P / _Nb] ^= (_T)1 << _P % _Nb;
  100.         return (*this); }
  101.     unsigned short to_ushort() const
  102.         {unsigned long _V = to_ulong();
  103.         if (~(unsigned short)0 < _V)
  104.             _Xoflo();
  105.         return (_V); }
  106.     unsigned long to_ulong() const
  107.         {enum {_Assert = 1 /
  108.             (sizeof (unsigned long) % sizeof (_T) == 0)};
  109.         int _I = _Nw;
  110.         unsigned long _V;
  111.         for (; sizeof (unsigned long) / sizeof (_T) <= _I; --_I)
  112.             if (_A[_I] != 0)
  113.                 _Xoflo();
  114.         for (_V = _A[_I]; 0 <= --_I; )
  115.             _V = _V << _Nb | _A[_I];
  116.         return (_V); }
  117.     string to_string() const
  118.         {string _S(_N, reserve);
  119.         for (size_t _P = _N; 0 < _P; )
  120.             _S += test(--_P) ? '1' : '0';
  121.         return (_S); }
  122.     size_t count() const
  123.         {size_t _V = 0;
  124.         for (int _I = _Nw; 0 <= _I; --_I)
  125.             for (_T _X = _A[_I]; _X != 0; _X >>= 4)
  126.                 _V += "\0\1\1\2\1\2\2\3"
  127.                     "\1\2\2\3\2\3\3\4"[_X & 0xF];
  128.         return (_V); }
  129.     size_t length() const
  130.         {return (_N); }
  131.     _Bool operator==(const bits<_N>& _R) const
  132.         {for (int _I = _Nw; 0 <= _I; --_I)
  133.             if (_A[_I] != _R._W(_I))
  134.                 return (0);
  135.         return (1); }
  136.     _Bool operator!=(const bits<_N>& _R) const
  137.         {return (!(*this == _R)); }
  138.     _Bool test(size_t _P) const
  139.         {if (_N <= _P)
  140.             _Xran();
  141.         return ((_A[_P / _Nb] & ((_T)1 << _P % _Nb)) != 0); }
  142.     _Bool any() const
  143.         {for (int _I = _Nw; 0 <= _I; --_I)
  144.             if (_A[_I] != 0)
  145.                 return (1);
  146.         return (0); }
  147.     _Bool none() const
  148.         {return (!any()); }
  149.     bits<_N> operator<<(size_t _R) const
  150.         {return (bits<_N>(*this) <<= _R); }
  151.     bits<_N> operator>>(size_t _R) const
  152.         {return (bits<_N>(*this) >>= _R); }
  153.     friend bits<_N> operator&(const bits<_N>& _L,
  154.         const bits<_N>& _R)
  155.         {return (bits<_N>(_L) &= _R); }
  156.     friend bits<_N> operator|(const bits<_N>& _L,
  157.         const bits<_N>& _R)
  158.         {return (bits<_N>(_L) |= _R); }
  159.     friend bits<_N> operator^(const bits<_N>& _L,
  160.         const bits<_N>& _R)
  161.         {return (bits<_N>(_L) ^= _R); }
  162.     friend istream& operator>>(istream& _I, bits<_N>& _R)
  163.         {_R = _Bitsxstr(_I, _N);
  164.         return (_I); }
  165.     friend ostream& operator<<(ostream& _O, const bits<_N>& _R)
  166.         {return (_O << _R.to_string()); }
  167.     _T _W(size_t _I) const
  168.         {return (_A[_I]); }
  169. private:
  170.     enum {_Nb = _BITS_BYTE * sizeof (_T),
  171.         _Nw = _N == 0 ? 0 : (_N - 1) / _Nb};
  172.     void _Tidy(_T _X = 0)
  173.         {for (int _I = _Nw; 0 <= _I; --_I)
  174.             _A[_I] = _X;
  175.         if (_X != 0)
  176.             _Trim(); }
  177.     void _Trim()
  178.         {if (_N % _Nb != 0)
  179.             _A[_Nw] &= ((_T)1 << _N % _Nb) - 1; }
  180.     void _Xinv() const
  181.         {invalidargument("invalid bits<N> char").raise(); }
  182.     void _Xoflo() const
  183.         {overflow("bits<N> conversion overflow").raise(); }
  184.     void _Xran() const
  185.         {outofrange("invalid bits<N> position").raise(); }
  186.     _T _A[_Nw + 1];
  187.     };
  188.  
  189. #if __MWERKS__
  190. #pragma options align=reset
  191. #endif
  192.  
  193. #endif
  194.  
  195. /*
  196.  * Copyright (c) 1994 by P.J. Plauger.  ALL RIGHTS RESERVED. 
  197.  * Consult your license regarding permissions and restrictions.
  198.  */
  199.  
  200. /* Change log:
  201.  *94June04 PlumHall baseline
  202.  *94Sept30 Applied diffs for Thu Aug 25 23:22:57 1994
  203.  *94Oct07 Inserted MW changes.
  204.  */
  205.